/*
 *  Copyright 2007 Marc Lanctot and Marc Gendron-Bellemare
 *
 *  This file is part of OpenMTG.
 *
 *  OpenMTG is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenMTG is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenMTG.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

import java.util.*; 

public class BaseAIPlayer extends AIClient
{
  protected volatile boolean playedLand;
  protected boolean decidingWhoStarts; 
  protected Card castingCard; 
  protected int castingStep;  
  protected ArrayList<Integer> landIDs; 
  protected boolean myTurn; 
  
  public BaseAIPlayer(String name, String host, int port, String deck)
  {
    super(name, host, port, deck);
  }
  
  public static void main(String[] args)
  {
    String host = null;
    String name = null;
    String deck = null;
    boolean verbose = false; 
    int port = -1;    

    for (int i = 0; i < args.length; i++)
    {
      if (args[i].equals("--port")) 
      {
        if (++i >= args.length) usage();
        port = Integer.parseInt(args[i]);
      }
      else if (args[i].equals("--host"))
      {
        if (++i >= args.length) usage();
        host = args[i];
      }
      else if (args[i].equals("--name"))
      {
        if (++i >= args.length) usage();
        name = args[i];
      }
      else if (args[i].equals("--deck"))
      {
        if (++i >= args.length) usage();
        deck = args[i];
      }
      else if (args[i].equals("--verbose") || args[i].equals("-v")) {
        verbose = true;
      }
      
    }

    if (port < 0 || host == null || name == null || deck == null) 
      usage();

    BaseAIPlayer c = new BaseAIPlayer(name, host, port, deck);
    c.setPrintMessages(verbose);    
    c.run();
  }  
  
  public boolean enableUI()
  {
    return false;  
  }  
  
  // Default impl
  protected void post_handle_hook(String inputLine)
  {
    String[] args = inputLine.split(" ");
    if (args.length < 1) return;
    String cmd = args[0];
    
    if (cmd.equals("GAMESTART"))
      handlePostGameStart(inputLine);
    else if (cmd.equals("PLAYERSTART"))
      handlePostPlayerStart(inputLine); 
    else if (cmd.equals("STARTTURN"))
      handlePostStartTurn(inputLine);
    else if (cmd.equals("CAST"))
      handlePostCast(inputLine);
    else if (cmd.equals("PLAYLAND"))
      handlePostPlayLand(inputLine);
    else if (cmd.equals("TAPFORMANA"))
      handlePostTapForMana(inputLine);
    else if (cmd.equals("RESEFF"))
      handlePostResEff(inputLine);
    else if (cmd.equals("ATTACK"))
      handlePostAttack(inputLine);
  }
  
  protected void resetVars()
  {
    playedLand = false; 
    castingCard = null; 
    castingStep = 0;
    landIDs = null; 
    myTurn = true;
  }
  
  protected void handlePostGameStart(String inputLine)
  {
    String[] parts = inputLine.split(" "); 
    int idToDecide = Integer.parseInt(parts[1]);

    //showState(); 

    if (idToDecide == me.getId())
    {
      // we decide who starts
      send("GAMESTART " + me.getId()); 
      decidingWhoStarts = true; 
    }
    else
    {
      // opponent is deciding who starts
    }
    
  }
  
  protected void handlePostPlayerStart(String inputLine)
  {
    String[] parts = inputLine.split(" ");
    int idToStart = Integer.parseInt(parts[1]);

    if (idToStart == me.getId()) {
      
      // we're taking first turn
      send("FIRSTTURN");
      
    } else {
      
      // opponent taking first turn
      send("FIRSTTURN");
    }

  }
  
  protected void handlePostStartTurn(String inputLine) 
  {
    System.out.println("Starting my turn... "); 
    
    if (turnPlayerId != me.getId()) {
      Player p = state.getPlayer(turnPlayerId);
      
      // other player's turn.
      myTurn = false; 
      
      return; 
    } 
        
    resetVars(); 
        
    // play a land if possible
    for (Card c : me.getHand()) {
      if (c.isLand()) {       
        send("PLAYLAND " + c.getIID());
        // if it worked wait for a response
        return; 
      }
    }
    
    resumeTurn1();
  }

  protected void handlePostCast(String inputLine) 
  {
    if (myTurn && castingCard != null) 
    {
      castingStep++; 
    }
    
    send("D"); 
  }
  
  protected void handlePostTapForMana(String inputLine)
  {
    String[] parts = inputLine.split(" ");
    
    int pid = Integer.parseInt(parts[1]);
    int iid = Integer.parseInt(parts[2]);
    
    //System.out.println("Got tfm, landIds size = " + landIDs.size());
    //System.out.println(iid); 
    
    if (landIDs.contains(iid))
    {
      int index = landIDs.indexOf(iid);  
      landIDs.remove(index); 
      System.out.println("Removing index " + index);
    }
    else 
    {
      // opponent tapping mana?
    }
    
    //System.out.println(landIDs.get(0)); 
    
    if (landIDs.size() == 0 && castingCard != null)
    {
      castingStep++; 
      resumeTurn2(); 
    }
  }
  
  protected void handlePostPlayLand(String inputLine)
  {
    if (myTurn)
    {
      synchronized(this)
      {
        playedLand = true;
      }
  
      resumeTurn1();
    }
  }
  
  protected void handlePostResEff(String inputLine)
  {
    if (myTurn)
    {
      castingStep++; 
      resumeTurn2(); 
    }
  }
  
  protected void handlePostAttack(String inputLine)
  {
    if (!myTurn)
    {
      send("D"); // don't block
    }
  }
  
  // ----------------------------------------------------------------------

  protected void resumeTurn1()
  {
    // see if i can cast anything
    for (Card c : me.getHand()) {
      if (c.isCreature())
        if (me.canCast(c.getIID()))
        {
          //System.out.println("I can cast " + c.toString()); 
          // choose to cast this one. 
          castingCard = c; 
          castingStep++; 
          
          landIDs = me.findLandsToCast(c.getIID()); 
          
          for (int iid : landIDs)
            send("TAPFORMANA " + iid); 
          
          return; 
        }
    }
    
    resumeTurn3(); 
  }
  
  protected void resumeTurn2()
  {
    if (castingStep == 2)
    {
      // mana is tapped; cast it.
      castingStep++; 
      send("CAST " + castingCard.getIID()); 
      return; 
    }
    else if (castingStep == 5)
    {
      // it's down! time to celebrate :) 
      castingCard = null; 
      castingStep = 0; 
    }
    else
    {
      Helpers.error("Should not get here! castingStep = " + castingStep);
    }
  
    // can you cast any more?
    resumeTurn1(); 
  }
  
  protected void resumeTurn3()
  {    
    if (!me.canAttack())
    {
      send("GO"); 
      send("GO"); 
      return; 
    }    

    // I should attack now! 
    //System.out.println("I should attack now.");
    
    send("GO"); 
    send("GO"); 
    send("GO"); 
    
    
  }
}